'''
Created on Feb 4, 2010

@author: oabalbin
'''

'''
It produces flat files, which can be upload later to a data base. 
Of the following form:
Interactor A, Interactor B, method


'''
import os
import glob
import signatures.db.tables as dt
import signatures.db.query as dq
import signatures.parsers.read_microarray_data as pr
import signatures.parsers.read_gene_lists as pg
from collections import deque, defaultdict


class protparser:
    
    def __init__(self, dbhost, dbuser, dbpasswd, database):
        self.mt = dt.tables(dbhost, dbuser, dbpasswd, database)
        self.mq = dq.query(dbhost, dbuser, dbpasswd, database)
        #table information
        self.tableDescription = 'protA VARCHAR(40), protB VARCHAR(40), method VARCHAR(100), INDEX pA (protA), INDEX pB (protB)'
        self.tableName = 'p2p_db'

    
    def parse_hprd(self, inputfile, outputfile):
        """
        It reads a file of protein interactions from HPRD.db
        """
        
        for line in inputfile:        
            line = line.strip('\n')
            fields = line.split('\t')
            # To skip headers, star reading samples in column 7 of the file
            if fields[0] == '#': 
                continue
            
            protA, protB, detectmethod = fields[3],fields[0],fields[6]
            methods = detectmethod.split(';')
            if 'yeast 2-hybrid' in methods:
                continue
            else:
                outputfile.write(protA+'\t'+protB+'\t'+detectmethod+'\n')
                
    def parse_mint(self, inputfile, outputfile):
        """
        It reads a file of protein interactions from MINT.db
        """
        hq_methods=['MI:0012(bioluminescence resonance energy transfer)','MI:0069(mass spectrometry studies of complexes)','MI:0019(coimmunoprecipitation)','MI:0872(atomic force microscopy)',
                    'MI:0826(x ray scattering)','MI:0515(methyltransferase assay)','MI:0055(fluorescent resonance energy transfer)','MI:0434(phosphatase assay)','MI:0007(anti tag coimmunoprecipitation)'
                    'MI:0424(protein kinase assay)','MI:0059(gst pull down)','MI:0512(zymography)','MI:0096(pull down)','MI:0406(deacetylase assay)','MI:0065(isothermal titration calorimetry)',
                    'MI:0067(light scattering)','MI:0114(x-ray crystallography)','MI:0025(copurification)','MI:0676(tandem affinity purification)','MI:0107(surface plasmon resonance)',
                    'MI:0405(competition binding)','MI:0028(cosedimentation in solution)','MI:0040(electron microscopy)']
        methods=[]
        for line in inputfile:        
            line = line.strip('\n')
            fields = line.split('\t')
            # To skip headers, star reading samples in column 7 of the file
            if fields[0] == '#': 
                continue
            
            protA, protB, detectmethod = fields[4],fields[5],fields[6]
            
            methods.append(detectmethod)
            
            if detectmethod in hq_methods:
                #print protA,protB, detectmethod
                outputfile.write(protA+'\t'+protB+'\t'+detectmethod+'\n')
                
        
    
    def parse_biogrid(self, inputfile, outputfile):
        """
        It reads a file of protein interactions from MINT.db
        """
        hd=False
        hq_methods=['Reconstituted Complex','Affinity Capture-Western','Co-crystal Structure','Protein-peptide','FRET']
        methods=[]
        for line in inputfile:        
            line = line.strip('\n')
            fields = line.split('\t')
            # To skip headers, star reading samples in column 7 of the file
            if fields[0] == '#': 
                continue
            if fields[0] == 'INTERACTOR_A':
                hd=True
                continue
            
            if hd:
                protA, protB, detectmethod, orgA, orgB = fields[2],fields[3],fields[6],fields[9],fields[10]
                
                methods.append(detectmethod)
                
    
                if (orgA == '9606' and orgB=='9606'):
                    if detectmethod in hq_methods:
                        outputfile.write(protA+'\t'+protB+'\t'+detectmethod+'\n')

        
    def parse_reactome(self, inputfile, outputfile, gen2symDict):
        """
        It reads a file of protein interactions from reactome.db
        """
        missKeys=[]
        for line in inputfile:        
            line = line.strip('\n')
            fields = line.split('\t')
            # To skip headers, star reading samples in column 7 of the file
            if fields[0][0] == '#': 
                continue
            
            protA, protB, detectmethod = fields[2],fields[5],fields[6]
            
            if (not protA or not protB):
                continue
            elif ('direct_complex' == detectmethod): 
                protA = protA.split(':')[1]
                protB = protB.split(':')[1]
                protA=protA.split('|')[0]
                protB=protB.split('|')[0]
                
                try:
                    genA = gen2symDict[protA]
                    genB = gen2symDict[protB]
                    outputfile.write(genA+'\t'+genB+'\t'+detectmethod+'\n')
                    
                except KeyError:
                    missKeys.append((protA, protB))
                    print 'Key missing in exp_mat ' + protA, protB
                    continue 
                        
                #outputfile.write(protA+'\t'+protB+'\t'+detectmethod+'\n')

    def parse_gen2symbol(self, inputfile, outputfile):
        """
        It reads a file of protein interactions from reactome.db
        """
        
        for line in inputfile:        
            line = line.strip('\n')
            fields = line.split('\t')
            # To skip headers, star reading samples in column 7 of the file
            if fields[0][0] == '#': 
                continue
            
            taxid, genA, genB = fields[0],fields[1],fields[2]
            
            if taxid == '9606':
                outputfile.write(genA+'\t'+genB+'\n')
                #print taxid, genA, genB


    def parse_gen2symDict(self, inputfile):
        """
        It reads a file of protein interactions from reactome.db
        """
        gen2SymDic={}
        for line in inputfile:        
            line = line.strip('\n')
            fields = line.split('\t')
            # To skip headers, star reading samples in column 7 of the file
            if fields[0][0] == '#': 
                continue
            
            genID, genSym = fields[0],fields[1]
            gen2SymDic[genID]=genSym
        
        return gen2SymDic
    
    def create_p2p_db(self, folderpath):
        """
        It creates a databases of p2p interactions using the files provided in the folderpath.
        """
        self.mt.create_connector()
        dbfiles=[]
        for infile in glob.glob( os.path.join(folderpath, '*.db') ):
            dbfiles.append(infile)

        for dbf in dbfiles:     
            if not(self.mt.table_existence(self.tableName)):
                self.mt.create_table(self.tableName,self.tableDescription)
                
            self.mt.load_data_table(self.tableName,dbf)
            
    def get_p2p_interactome(self,genelist):
        """
        It queries a database of p2p for a particular gene
        retrieves the protein to protein interactions associated with it.
        """
        itcome=[]
        for g in genelist:
            itcome = self.mq.get_p2p_interations(g,itcome)
        
        return list(set(itcome))
    
    def get_p2p_interactome_byBait(self,genelist):
        """
        It queries a database of p2p for a particular gene
        retrieves the protein to protein interactions associated with it.
        """
        itcome=defaultdict(list)
        for g in genelist:
            itcome = self.mq.get_p2p_interations_byBait(g,itcome)
        
        return itcome

    
    def write_p2p_interactome(self,genelist, outputfile):
        """
        writes a long line with all genes that belong to the interactome.
        """
        for g in genelist:
            outputfile.write(g+'\t')
            
        outputfile.write('\n')
    
    def write_p2p_interactome_byBait(self,interactomeDict, outputfile):
        """
        writes a long line with all genes that belong to the interactome.
        """
        for gene,interactions in interactomeDict.iteritems():
            outputfile.write(gene+'\t'+",".join(interactions).replace(',','\t')+'\n')
            
        outputfile.write('\n')
    
    
    def write_p2p_interactome_byBait_cytoscape(self,interactomeDict, outputfile):
        """
        writes a long line with all genes that belong to the interactome.
        """
        header = ["source","target","interaction","boolean_attribute"]
        outputfile.write(",".join(header).replace(",","\t")+'\n')
    
        for gene,interactions in interactomeDict.iteritems():
            [outputfile.write(gene+'\t'+prot+'\t'+"pp"+'\t'+"TRUE"+'\n') for prot in interactions]
                #outputfile.write(gene+'\t'+prot+'\t'+"pp"+'\t'+"TRUE"+'\n')
            
        outputfile.write('\n')


prt = protparser("localhost", "oabalbin", "oscar", "signatures")
#prt.parse_hprd(open('/home/oabalbin/downloads/Protein_Interactions/HPRD_Release_8_070609/BINARY_PROTEIN_PROTEIN_INTERACTIONS.txt'), open('/home/oabalbin/projects/networks/prot_intc_db/HPRD.db','w'))

#prt.parse_mint(open('/home/oabalbin/downloads/Protein_Interactions/2009-11-05-mint-human.txt'), open('/home/oabalbin/projects/networks/prot_intc_db/MINT.db','w'))
#prt.parse_biogrid(open('/home/oabalbin/downloads/Protein_Interactions/BIOGRID-ALL-2.0.61.tab.txt'), open('/home/oabalbin/projects/networks/prot_intc_db/Biogrid.db','w'))
#prt.parse_gen2symbol(open('/home/oabalbin/downloads/Protein_Interactions/gene_info'), open('/home/oabalbin/projects/networks/prot_intc_db/gen2symbol.db','w'))
#gen2symDic = prt.parse_gen2symDict(open('/home/oabalbin/projects/networks/prot_intc_db/gen2symbol.db'))
#prt.parse_reactome(open('/home/oabalbin/downloads/Protein_Interactions/homo_sapiens.interactions.txt'), open('/home/oabalbin/projects/networks/prot_intc_db/reactome.db','w'),gen2symDic)

#prt.create_p2p_db('/home/oabalbin/projects/networks/prot_intc_db/')

'''
mpr = pr.parser()
mgp = pg.geneparser()
#geneList = mpr.list_of_names(open('/home/oabalbin/projects/networks/seed_genes/all_erg_complex_genes'))
#geneList = mpr.list_of_names(open('/home/oabalbin/projects/networks/Kinases_lists/output/first_outliers_genes'))
#cell_oultliersList = mgp.list_of_names_in_line_dictionary(open('/home/oabalbin/projects/networks/Kinases_lists/outliers_allcells.txt'))
cell_oultliersList = mgp.list_of_names_in_line_dictionary(open('/home/oabalbin/projects/networks/Kinases_lists/all_outliers_onlygenes.txt'))
#interactome = prt.get_p2p_interactome(geneList)
i=0
for cell, geneList in cell_oultliersList.iteritems():
    print cell, geneList
    interactome = prt.get_p2p_interactome_byBait(geneList)
    #outputfilename = '/home/oabalbin/projects/networks/Kinases_lists/output/first_outliers_genes_interactome_'+cell+'_'+str(i)+'.db'
    outputfilename = '/home/oabalbin/projects/networks/Kinases_lists/output/all_outliers_onlygenes_'+cell+'_'+str(i)+'.db'
    prt.write_p2p_interactome_byBait_cytoscape(interactome,open(outputfilename,'w'))
    i+=1
'''